﻿using DataWorks_Sqlite.MappingClass;
using DataWorks_Tools.BasicMethods;
using DataWorks_Tools.DBC.DBCCSV;
using DataWorks_Tools.MappModals;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataWorks_Tools.DBC.DBCProcess
{
    public static class DBCMessageTransferUnify
    {
        private static readonly string canname = "can";
        public static async Task<List<string>> DBCMessageTransferProcessExcute(Dictionary<(uint Device, uint Channel), DbcParserLib.Model.Message[]> mes,DBCMessageTransferModal row)
        {
            // 存储执行日志或提示信息
            List<string> list = new List<string>();
            // 确保结果保存路径存在
            Directory.CreateDirectory(row.rdpath);
            // 获取源数据路径下的日期文件夹和用户填写的日期，如用户有指定日期，则只处理指定日期的数据，如为all则所有都处理
            var ds = BasicFilesOperation.YXHGetProcessedDateDirforDBCMessage(row.odpath,row.datedir);
            // 若没有找到任何待处理的文件夹，则直接返回
            if (ds == null || ds.Length == 0)
            {
                list.Add($"目标路径{row.rdpath}下无日期文件夹");
                return list;
            }
            try
            {
                Stopwatch Btimer = new Stopwatch();
                Btimer.Start();
                foreach (var d in ds)
                {
                    Stopwatch Stimer = new Stopwatch();
                    Stimer.Start();
                    //先定义输出日期目录文件夹路径
                    string csvdatedir = Path.Combine(row.rdpath, d.Name);
                    // 日期文件夹下面还有can文件夹
                    var candatadir = Path.Combine(d.FullName, canname);
                    // 获取所有的gz文件
                    var gzlst = BasicFilesOperation.YXHGetAllextFiles(candatadir, "*.gz");
                    //如果文件夹下没有csv文件
                    if (gzlst == null || gzlst.Length == 0)
                    {
                        list.Add($"{d.Name}文件夹下没有gz文件或文件夹路径有问题");
                        return list;
                    }
                    DirectoryInfo root = new DirectoryInfo(csvdatedir);
                    //创建日期目录文件夹
                    if (!root.Exists)
                    {
                        root.Create();
                    }
                    var csvlst = BasicFilesOperation.YXHGetAllextFiles(csvdatedir, "*.csv");
                    //获得需要报文转csv的gz文件名（带路径）列表，因为目标文件夹有可能已经有转换好的数据，如果有则剔除这部分gz文件
                    var gzneedtotransfer = await DBCCSVWriter.GetRemainingFileNamesAsync(gzlst, csvlst);
                    if (gzneedtotransfer == null || gzneedtotransfer.Count == 0)
                    {
                        list.Add($"你傻了吧，{d.Name}文件夹下gz文件已全部转换完成");
                        return list;
                    }
                    foreach (var gz in gzneedtotransfer)
                    {
                        var r1 = await DBCProcess.ExtractCanSignalsAsync(mes, gz.FullName);
                        //转换名字 can_20250924_181043_1.csv.gz → 2025_09_24-18_10_43-1-F.csv
                        var newcsvname = await gz.Name.ConvertCanFileNameToFAsync();
                        //获得存储csv的目标文件路径，用于保存转换后的csv
                        string csvfilepath = Path.Combine(csvdatedir, newcsvname);
                        await DBCProcess.ResampleAndSaveCsv(r1, csvfilepath);
                    }
                    Stimer.Stop();
                    list.Add($"{d.Name}报文转换完成时间为{Stimer.Elapsed.TotalMinutes:0.00}分");
                }
                Btimer.Stop();
                list.Add($"报文转换总完成时间为{Btimer.Elapsed.TotalMinutes.ToString("0.00")}分-单线程");
                return list;

            }
            catch (Exception ex)
            {
                list.Add($"程序出错：{ex.Message}");
                return list;
            }

        }

        public static async Task<List<string>> DBCMessageTransferProcessMultithreadedExecute(Dictionary<(uint Device, uint Channel), DbcParserLib.Model.Message[]> mes, DBCMessageTransferModal row)
        {
            // 存储执行日志或提示信息
            List<string> list = new List<string>();
            // 确保结果保存路径存在
            Directory.CreateDirectory(row.rdpath);
            // 获取源数据路径下的日期文件夹和用户填写的日期，如用户有指定日期，则只处理指定日期的数据，如为all则所有都处理
            var ds = BasicFilesOperation.YXHGetProcessedDateDirforDBCMessage(row.odpath, row.datedir);
            // 若没有找到任何待处理的文件夹，则直接返回
            if (ds == null || ds.Length == 0)
            {
                list.Add($"目标路径{row.rdpath}下无日期文件夹");
                return list;
            }
            try
            {
                Stopwatch Btimer = new Stopwatch();
                Btimer.Start();

                // 创建一个用于保存所有任务的列表
                var tasks = new List<Task>();

                foreach (var d in ds)
                {
                    // 将每个文件夹的处理封装成一个任务，并添加到任务列表
                    tasks.Add(Task.Run(async () =>
                    {
                        Stopwatch Stimer = new Stopwatch();
                        Stimer.Start();

                        // 定义输出日期目录文件夹路径
                        string csvdatedir = Path.Combine(row.rdpath, d.Name.ConvertFileNameToDateFormat());
                        // 日期文件夹下面还有can文件夹
                        var candatadir = Path.Combine(d.FullName, canname);
                        // 获取所有的gz文件
                        var gzlst = BasicFilesOperation.YXHGetAllextFiles(candatadir, "*.gz");

                        // 如果文件夹下没有gz文件
                        if (gzlst == null || gzlst.Length == 0)
                        {
                            lock (list) list.Add($"{d.Name}文件夹下没有gz文件或文件夹路径有问题");
                            return;
                        }

                        DirectoryInfo root = new DirectoryInfo(csvdatedir);
                        // 创建日期目录文件夹
                        if (!root.Exists)
                        {
                            root.Create();
                        }

                        var csvlst = BasicFilesOperation.YXHGetAllextFiles(csvdatedir, "*.csv");
                        // 获得需要报文转csv的gz文件名（带路径）列表
                        var gzneedtotransfer = await DBCCSVWriter.GetRemainingFileNamesAsync(gzlst, csvlst);
                        if(gzneedtotransfer==null||gzneedtotransfer.Count==0)
                        {
                            lock (list) list.Add($"你傻了吧，{d.Name}文件夹下gz文件已全部转换完成");
                            return;
                        }
                        foreach (var gz in gzneedtotransfer)
                        {
                            var r1 = await DBCProcess.ExtractCanSignalsAsync(mes, gz.FullName);
                            // 转换名字 can_20250924_181043_1.csv.gz → 2025_09_24-18_10_43-1-F.csv
                            var newcsvname = await gz.Name.ConvertCanFileNameToFAsync();
                            // 获得存储csv的目标文件路径
                            string csvfilepath = Path.Combine(csvdatedir, newcsvname);
                            await DBCProcess.ResampleAndSaveCsv(r1, csvfilepath);
                        }

                        Stimer.Stop();
                        lock (list) list.Add($"{d.Name}报文转换完成时间为{Stimer.Elapsed.TotalMinutes:0.00}分");

                        //筛选所有txt并复制到目标文件夹下
                        var txtinfo = BasicFilesOperation.YXHGetAllextFiles(d.FullName, "*.txt");
                        foreach (var file in txtinfo)
                        {
                            var txtresultpath = Path.Combine(csvdatedir, file.Name);
                            file.CopyTo(txtresultpath, true);
                        }

                    }));
                }

                // 等待所有任务完成
                await Task.WhenAll(tasks);

             
                Btimer.Stop();
                lock (list) list.Add($"报文转换总完成时间为{Btimer.Elapsed.TotalMinutes.ToString("0.00")}分-多线程");

                return list;

            }
            catch (Exception ex)
            {
                lock (list) list.Add($"程序出错：{ex.Message}");
                return list;
            }
        }

    }
}
